<?php

namespace App\Libraries\Sign;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use LTools\Contracts\Sign\SignDriverInterface;
use LTools\Sign\SignAbstract;

class Md5 extends SignAbstract implements SignDriverInterface
{
    private $signKey;

    /**
     * @param $signKey
     */
    public function __construct($signKey)
    {
        $this->signKey = $signKey;
    }

    /**
     * 签名.
     *
     * @method sign
     *
     * @param array $data
     *
     * @return string
     *
     * @author luffyzhao@vip.126.com
     */
    public function sign(array $data): string
    {
        // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        return md5(
            $this->createLinkstring($this->sortKeys($data)).$this->getSignKey()
        );
    }

    /**
     * 验证签名.
     *
     * @method verify
     *
     * @param array $data
     * @param string $sign
     *
     * @return bool
     *
     * @author luffyzhao@vip.126.com
     */
    public function verify(array $data, string $sign): bool
    {
        if(isset($data['sign'])){
            unset($data['sign']);
        }
        $strSign = md5(
            $this->createLinkstring($this->sortKeys($data)).$this->getSignKey()
        );
        Log::error($strSign);
        return $strSign == $sign;
    }

    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串.
     *
     * @method createLinkString
     *
     * @param array $data
     * @param string $pix
     * @return string
     *
     * @author luffyzhao@vip.126.com
     */
    protected function createLinkString(array $data, $pix = ''): string
    {
        $sign = '';
        if (!empty($data)) {
            foreach ($data as $key => $val) {
                $key = ('' === $pix ? $key : $pix."[{$key}]");
                if (is_object($val) || is_array($val)) {
                    $val = (array)$val;
                    if (!empty($val)) {
                        $sign .= $this->createLinkString((array)$val, $key).'&';
                    } else {
                        $sign .= $key.'=&';
                    }
                } else {
                    $sign .= $key.'='.urlencode($val).'&';
                }
            }
        }
        //去掉最后一个&字符
        $sign = trim($sign, '&');
        return $sign;
    }

    /**
     * @return string
     */
    private function getSignKey(): string
    {
        return $this->signKey;
    }
}
